'''
    该源码用于将音乐卡点的合成视频转换成720*1280的视频
    旁边视频内容为1920*1080的视频的中间部分
'''
import random
import httpx
import os
from moviepy.editor import*
from src.Snowflake import SnowflakeIDGenerator
from decimal import Decimal
import cv2
import subprocess

def my_round(num, decimals=0):
    multiplier = 10 ** decimals
    return int(num * multiplier + 0.5) / multiplier

class VideoConcatenator:
    def __init__(self, video_files, durations, mute_original=True, new_audio_file=None, auto_slow=False):
        self.video_files = video_files
        self.durations = durations
        self.mute_original = mute_original
        self.new_audio_file = new_audio_file
        self.video_clips = []
        self.auto_slow = auto_slow

    @property
    def concatenate_videos(self):
        for file, duration in zip(self.video_files, self.durations):
            clip = VideoFileClip(file, target_resolution=[1920, 1080])
            # 关闭原视频的声音
            if self.mute_original:
                clip = clip.set_audio(None)

            actual_duration = clip.duration

            if actual_duration < duration:
                #  如果需要拼接的视频不满足目标长度，可以选择慢放或者自动最后一帧补全
                if self.auto_slow:
                    speed = my_round(actual_duration/duration,2) + 0.01
                    print(f"视频长度不满足，慢放{speed}倍速率")
                    clip = clip.fl_time(lambda t: speed*t, apply_to=['mask', 'video', 'audio']).set_end(duration)
                else:
                    last_frame = clip.to_ImageClip(t=actual_duration-0.01, duration=duration - actual_duration)
                    clip = concatenate_videoclips([clip, last_frame])

            clip = clip.subclip(0, duration)
            transitions = ['fadein', 'fadeout']
            transition_effect = random.choice(transitions)
            video_1920_1080 = getattr(clip, transition_effect)(0.2)
            video_1280_720 = video_1920_1080\
                .crop(x1=0, y1=video_1920_1080.w, x2=1280, y2=video_1920_1080.w-600-720)\
                .resize((1280, 720))\
                .fl_image(blur_frame)\
                .fl_image(blur_frame)\
                .fl_image(blur_frame)
            mid_video = video_1920_1080.fx(vfx.resize, height=720)
            video_1280_720 = CompositeVideoClip([video_1280_720.set_duration(video_1280_720.duration), mid_video.set_position(("center"))])
            self.video_clips.append(video_1280_720)


        final_clip = concatenate_videoclips(self.video_clips, method="compose")
        # 替换声音
        if self.new_audio_file:
            audio_clip = AudioFileClip(self.new_audio_file)
            final_clip = final_clip.set_audio(audio_clip)
        return final_clip

    def write_output(self, output_file,add_vfx=None):
        final_clip = self.concatenate_videos
        if add_vfx:
            for name in add_vfx:
                final_clip = final_clip.fx(name)
        final_clip.write_videofile(output_file, codec="libx264", audio_codec="aac", preset="ultrafast", fps=30)

# 定义一个函数来对视频的每一帧进行模糊处理
def blur_frame(frame):
    blurred_frame = cv2.GaussianBlur(frame, (35, 35), 0)  # 使用高斯模糊进行模糊处理
    return blurred_frame

def create_directory_if_not_exists(file_path):
    directory = os.path.dirname(file_path)

    # 检查文件夹是否存在，如果不存在则创建
    if not os.path.exists(directory):
        os.makedirs(directory)


def read_and_split_file(file_path):
    # 打开文件并读取每一行
    with open(file_path, 'r') as file:
        lines = file.readlines()
    # 分割每一行并组成数组
    return [Decimal(line.strip()) for line in lines]


def read_beat_to_duration(beatArray):
    last_beat = Decimal('0')
    i = 0
    duration = []
    while i < len(beatArray):
        duration.append(float(beatArray[i] - last_beat))
        last_beat = beatArray[i]
        i += 1
    return duration
def repair_video(input, repaired_output_dir, repair_bat_path):
    cmd = f"{repair_bat_path}repair_video.bat -pydir {repair_bat_path} -i {input} -o {repaired_output_dir} -w 0.5 -bu None -fps 30"
    print(f"cmd命令为{cmd}")
    os.system(cmd)

if __name__ == "__main__":
    # 转义用户输入的字符串
    param = "张雅倩_正脸"
    audio_name = "2024-02-08 21.11.25-希希3-g@o.DU 过节啦～新年快乐"
    audio_file = f"music/{audio_name}.mp3"
    beat_file = f"beat/{audio_name}.txt"
    repaired_output_dir = f"outputRepaired"

    # 生成的文件名称
    out_put = f"output\\{SnowflakeIDGenerator().generate_id()}.mp4"
    # url = "http://127.0.0.1:48080/app-api/douyinFileInfo/select/collect/random/single/works"
    # url = "http://127.0.0.1:48080/app-api/douyinFileInfo/select/collect/findAll/collect"
    # url = "https://ppru.cn/api/douyinFileInfo/select/collect/random/single/works"
    url = "https://ppru.cn/api/douyinFileInfo/select/collect/findAll/collect"
    videoPath = "E:\\clip"
    # 修复视频的bat脚本
    repair_bat_path = "D:\\software\\codeFormer-GUI\\"

    # 合成视频
    r = httpx.post(url=url, json={"tag":param})
    results = r.json()['data']
    # 替换以下信息为你的视频文件路径和时长
    beat_array = read_and_split_file(beat_file)
    video_paths = random.sample([videoPath + result['path'] for result in results], len(beat_array))
    durations = read_beat_to_duration(beat_array)
    concatenator = VideoConcatenator(video_paths, durations, new_audio_file=audio_file, auto_slow=True)
    create_directory_if_not_exists(out_put)
    concatenator.write_output(out_put,add_vfx=[vfx.mirror_x])

    # 修复视频
    # out_put =  "output\\1.mp4"
    # repaired_output_dir = os.getcwd() + os.sep + repaired_output_dir
    # out_put = os.getcwd() + os.sep + out_put
    # repair_video(out_put, repaired_output_dir, repair_bat_path)